//
// Created by twetec on 25-7-10.
//

#include <network_prober/utils/snowflake_uuid_generator.h>

/**
 * 数据中心ID
 */
static const std::uint16_t kDataCenterID = 1;

/**
 * 工作机ID
 */
static const std::uint16_t kWorkerID = 1;


namespace network_prober::utils
{
SnowflakeUUIDGenerator::SnowflakeUUIDGenerator()
    : m_datacenterId(kDataCenterID), m_workerId(kWorkerID), m_sequence(0), m_lastTimestamp(0)
{
    if (m_datacenterId > m_maxDatacenterId || m_workerId > m_maxWorkerId) {
        throw std::invalid_argument("Invalid datacenter or worker ID");
    }
}

std::uint64_t SnowflakeUUIDGenerator::generate()
{
    std::unique_lock<std::mutex> lock(m_mutex);

    uint64_t timestamp = _currentTimestamp();

    if (timestamp < m_lastTimestamp) {
        throw std::runtime_error("Clock moved backwards");
    }

    //时间戳原理:获取当前时间戳如果等于上次时间戳(同一毫秒内),咋序列号加一。否则序列号设置为0，从0开始
    if (timestamp == m_lastTimestamp) {
        m_sequence = (m_sequence + 1) & m_sequenceMask;
        if (m_sequence == 0) {
            timestamp = _waitNextMillis(m_lastTimestamp);
        }
    } else {
        m_sequence = 0;
    }

    m_lastTimestamp = timestamp;

    return ((timestamp - m_twepoch) << m_timestampLeftShift) |
           ((m_datacenterId & m_maxDatacenterId) << m_datacenterIdShift) |
           ((m_workerId & m_maxWorkerId) << m_workerIdShift) |
           (m_sequence & m_sequenceMask);
}

uint64_t SnowflakeUUIDGenerator::_currentTimestamp() const
{
    return std::time(nullptr) * 1000;
}

uint64_t SnowflakeUUIDGenerator::_waitNextMillis(uint64_t lastTimestamp)
{
    uint64_t timestamp = _currentTimestamp();
    while (timestamp <= lastTimestamp) {
        timestamp = _currentTimestamp();
    }
    return timestamp;
}

SnowflakeUUIDGenerator &SnowflakeUUIDGenerator::getInstance()
{
    static SnowflakeUUIDGenerator instance;
    return instance;
}

SnowflakeUUIDGenerator::~SnowflakeUUIDGenerator()
{

}

}